﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Management;
using System.IO.Ports;

namespace RoboXeroSerial
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        // キーと値をセットで保存。「COM1」が「標準シリアルポート1」など。
        Dictionary<string, string> ComPortTable = new Dictionary<string, string>();

        // シリアルポートのインスタンス作成。
        SerialPort serialPort = new SerialPort();

        public MainWindow()
        {
            InitializeComponent();

            // シリアルポートの実装状況を取得。
            ManagementClass mcW32SerialPort = new ManagementClass("Win32_SerialPort");
            foreach (ManagementObject aSerialPort in mcW32SerialPort.GetInstances())
            {
                ComPortTable.Add(
                    (string)aSerialPort.GetPropertyValue("Caption"),
                    (string)aSerialPort.GetPropertyValue("DeviceID"));
            }
            string[] ports = SerialPort.GetPortNames();
            foreach (string port in ports)
            {
                if (!ComPortTable.ContainsValue(port))
                {
                    ComPortTable.Add(port, port);
                }
            }
        }

        private byte getV120ByteValue()
        {
            byte v120 = 0x00;

            if (cbxV120bit1.IsChecked == true)
            {
                v120 += 1;
            }
            if (cbxV120bit2.IsChecked == true)
            {
                v120 += 2;
            }
            if (cbxV120bit3.IsChecked == true)
            {
                v120 += 4;
            }
            if (cbxV120bit4.IsChecked == true)
            {
                v120 += 8;
            }
            if (cbxV120bit5.IsChecked == true)
            {
                v120 += 16;
            }
            if (cbxV120bit6.IsChecked == true)
            {
                v120 += 32;
            }
            if (cbxV120bit7.IsChecked == true)
            {
                v120 += 64;
            }
            if (cbxV120bit8.IsChecked == true)
            {
                v120 += 128;
            }

            return v120;
        }

        private byte getV121ByteValue()
        {
            byte v121 = 0x00;

            if (cbxV121bit1.IsChecked == true)
            {
                v121 += 1;
            }
            if (cbxV121bit2.IsChecked == true)
            {
                v121 += 2;
            }
            if (cbxV121bit3.IsChecked == true)
            {
                v121 += 4;
            }
            if (cbxV121bit4.IsChecked == true)
            {
                v121 += 8;
            }
            if (cbxV121bit5.IsChecked == true)
            {
                v121 += 16;
            }
            if (cbxV121bit6.IsChecked == true)
            {
                v121 += 32;
            }
            if (cbxV121bit7.IsChecked == true)
            {
                v121 += 64;
            }
            if (cbxV121bit8.IsChecked == true)
            {
                v121 += 128;
            }

            return v121;
        }

        private byte makeCheckSum()
        {
            byte checkSum = 0x00;
            byte[] data = new byte[6];
            short work = 0;

            // 画面からデータを取得。
            data[0] = Convert.ToByte(tbxV120.Text, 16);
            data[1] = Convert.ToByte(tbxV121.Text, 16);
            data[2] = Convert.ToByte(tbxV122.Text, 16);
            data[3] = Convert.ToByte(tbxV123.Text, 16);
            data[4] = Convert.ToByte(tbxV124.Text, 16);
            data[5] = Convert.ToByte(tbxV125.Text, 16);

            for (int i = 0; i < 6; i++)
            {
                work += data[i];
            }

            checkSum = (byte)( 0x7F & work);
            
            return checkSum;
        }

        private bool makeRoboXeroComand(ref byte[] byteData)
        {
            bool isSuccess = false;

            //byte[] data = new byte[8];

            try
            {
                // 画面からデータを取得。
                byteData[0] = 0x80;     // 0x80固定
                byteData[1] = Convert.ToByte(tbxV120.Text, 16);
                byteData[2] = Convert.ToByte(tbxV121.Text, 16);
                byteData[3] = Convert.ToByte(tbxV122.Text, 16);
                byteData[4] = Convert.ToByte(tbxV123.Text, 16);
                byteData[5] = Convert.ToByte(tbxV124.Text, 16);
                byteData[6] = Convert.ToByte(tbxV125.Text, 16);
                byteData[7] = Convert.ToByte(tbxV126.Text, 16);

                isSuccess = true;
            }
            catch (Exception ex)
            {
                string errMsg = "makeRoboXeroComand(ref byte[] byteData)関数でエラー";
                errMsg += ex.Message;
                Console.WriteLine(errMsg);
                MessageBox.Show(errMsg);

                isSuccess = false;
            }
            
            return isSuccess;
        }

        private bool sendRoboXeroCommand(byte[] sendData)
        {
            bool isSuccess = false;

            try
            {
                if (serialPort.IsOpen)
                {
                    serialPort.Write(sendData, 0, sendData.Length);
                }

                isSuccess = true;
            }
            catch (Exception ex)
            {
                string errMsg = "sendRoboXeroCommand(byte[] sendData)関数でエラー";
                errMsg += ex.Message;
                Console.WriteLine(errMsg);
                MessageBox.Show(errMsg);

                isSuccess = false;
            }

            return isSuccess;
        }

        private void mainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            // 画面の構成。

            // シリアルポートのコンボボックス構成。
            cmbPortNo.Items.Clear();
            foreach (string aPortCaption in ComPortTable.Keys)
            {
                cmbPortNo.Items.Add(aPortCaption);
            }
            if (ComPortTable.Count > 0)
            {
                cmbPortNo.SelectedIndex = 0;
            }
            else
            {
                MessageBox.Show("シリアルポートが存在しません。");
            }

            // シリアルポート「接続」「切断」ボタン。
            btnConnect.IsEnabled = true;
            btnDisConnect.IsEnabled = false;
            btnSend.IsEnabled = false;

            // 通信速度ラジオボタン
            radioWired.IsChecked = true;
            radioWired.IsEnabled = true;
            radioRadio.IsEnabled = true;

            // チェックボックスクリア
            cbxV120bit8.IsChecked = false;
            cbxV120bit7.IsChecked = false;
            cbxV120bit6.IsChecked = false;
            cbxV120bit5.IsChecked = false;
            cbxV120bit4.IsChecked = false;
            cbxV120bit3.IsChecked = false;
            cbxV120bit2.IsChecked = false;
            cbxV120bit1.IsChecked = false;
            tbxV120.Text
                = ((int)getV120ByteValue()).ToString("X2");

            cbxV121bit8.IsChecked = false;
            cbxV121bit7.IsChecked = false;
            cbxV121bit6.IsChecked = false;
            cbxV121bit5.IsChecked = false;
            cbxV121bit4.IsChecked = false;
            cbxV121bit3.IsChecked = false;
            cbxV121bit2.IsChecked = false;
            cbxV121bit1.IsChecked = false;
            tbxV121.Text
                = ((int)getV121ByteValue()).ToString("X2");

            // スライダ値域・初期値設定
            sliderV122.Minimum = 0x00;      // 最小値0
            sliderV122.Maximum = 0x7f;      // 最大値127
            sliderV122.Value = 0x40;        // 初期値64
            txtV122dec.Content 
                = Convert.ToString((int)sliderV122.Value, 10);
            tbxV122.Text
                = ((int)sliderV122.Value).ToString("X2");

            sliderV123.Minimum = 0x00;      // 最小値0
            sliderV123.Maximum = 0x7f;      // 最大値127
            sliderV123.Value = 0x40;        // 初期値64
            txtV123dec.Content
                = Convert.ToString((int)sliderV123.Value, 10);
            tbxV123.Text
                = ((int)sliderV123.Value).ToString("X2");

            sliderV124.Minimum = 0x00;      // 最小値0
            sliderV124.Maximum = 0x7f;      // 最大値127
            sliderV124.Value = 0x40;        // 初期値64
            txtV124dec.Content
                = Convert.ToString((int)sliderV124.Value, 10);
            tbxV124.Text
                = ((int)sliderV124.Value).ToString("X2");

            sliderV125.Minimum = 0x00;      // 最小値0
            sliderV125.Maximum = 0x7f;      // 最大値127
            sliderV125.Value = 0x40;        // 初期値64
            txtV125dec.Content
                = Convert.ToString((int)sliderV125.Value, 10);
            tbxV125.Text
                = ((int)sliderV125.Value).ToString("X2");
        }

        private void btnConnect_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                string comPort = ComPortTable[cmbPortNo.SelectedItem.ToString()];
                if (comPort != null)
                {
                    // COMポート接続。
                    serialPort.PortName = comPort;
                    if (serialPort.IsOpen)
                    {
                        MessageBox.Show("既に" + comPort + "はオープンされています。");
                    }
                    else
                    {
                        if (radioWired.IsEnabled == true)
                        {
                            serialPort.BaudRate = 115200;
                        }
                        else
                        {
                            serialPort.BaudRate = 2400;
                        }
                        serialPort.Parity = System.IO.Ports.Parity.None;
                        serialPort.StopBits = System.IO.Ports.StopBits.One;
                        serialPort.DataBits = 8;
                        serialPort.Open();
                        btnConnect.IsEnabled = false;
                        btnDisConnect.IsEnabled = true;
                        radioWired.IsEnabled = false;
                        radioRadio.IsEnabled = false;
                        btnSend.IsEnabled = true;
                    }
                }
            }
            catch (Exception ex)
            {
                if (serialPort.IsOpen) serialPort.Close();
                string errMsg = "@btnConnect_Click():";
                errMsg += ex.Message;
                Console.WriteLine(errMsg);
                btnConnect.IsEnabled = true;
                btnDisConnect.IsEnabled = false;
                radioWired.IsEnabled = true;
                radioRadio.IsEnabled = true;
                btnSend.IsEnabled = false;
            }
        }

        private void btnDisConnect_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (serialPort.IsOpen)
                {
                    serialPort.Close();
                    btnConnect.IsEnabled = true;
                    btnDisConnect.IsEnabled = false;
                    radioWired.IsEnabled = true;
                    radioRadio.IsEnabled = true;
                    btnSend.IsEnabled = false;
                }
            }
            catch (Exception ex)
            {
                string errMsg = ex.Message;
                Console.WriteLine(errMsg);
                MessageBox.Show(errMsg);
            }
        }

        private void btnEnd_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }

        private void cbxV120bit1_Checked(object sender, RoutedEventArgs e)
        {
            tbxV120.Text
                = ((int)getV120ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV120bit1_Unchecked(object sender, RoutedEventArgs e)
        {
            tbxV120.Text
                = ((int)getV120ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV120bit2_Checked(object sender, RoutedEventArgs e)
        {
            tbxV120.Text
                = ((int)getV120ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV120bit2_Unchecked(object sender, RoutedEventArgs e)
        {
            tbxV120.Text
                = ((int)getV120ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV120bit3_Checked(object sender, RoutedEventArgs e)
        {
            tbxV120.Text
                = ((int)getV120ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV120bit3_Unchecked(object sender, RoutedEventArgs e)
        {
            tbxV120.Text
                = ((int)getV120ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV120bit4_Checked(object sender, RoutedEventArgs e)
        {
            tbxV120.Text
                = ((int)getV120ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV120bit4_Unchecked(object sender, RoutedEventArgs e)
        {
            tbxV120.Text
                = ((int)getV120ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV120bit5_Checked(object sender, RoutedEventArgs e)
        {
            tbxV120.Text
                = ((int)getV120ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV120bit5_Unchecked(object sender, RoutedEventArgs e)
        {
            tbxV120.Text
                = ((int)getV120ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV120bit6_Checked(object sender, RoutedEventArgs e)
        {
            tbxV120.Text
                = ((int)getV120ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV120bit6_Unchecked(object sender, RoutedEventArgs e)
        {
            tbxV120.Text
                = ((int)getV120ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV120bit7_Checked(object sender, RoutedEventArgs e)
        {
            tbxV120.Text
                = ((int)getV120ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV120bit7_Unchecked(object sender, RoutedEventArgs e)
        {
            tbxV120.Text
                = ((int)getV120ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV120bit8_Checked(object sender, RoutedEventArgs e)
        {
            tbxV120.Text
                = ((int)getV120ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV120bit8_Unchecked(object sender, RoutedEventArgs e)
        {
            tbxV120.Text
                = ((int)getV120ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV121bit1_Checked(object sender, RoutedEventArgs e)
        {
            tbxV121.Text
                = ((int)getV121ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV121bit1_Unchecked(object sender, RoutedEventArgs e)
        {
            tbxV121.Text
                = ((int)getV121ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV121bit2_Checked(object sender, RoutedEventArgs e)
        {
            tbxV121.Text
                = ((int)getV121ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV121bit2_Unchecked(object sender, RoutedEventArgs e)
        {
            tbxV121.Text
                = ((int)getV121ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV121bit3_Checked(object sender, RoutedEventArgs e)
        {
            tbxV121.Text
                = ((int)getV121ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV121bit3_Unchecked(object sender, RoutedEventArgs e)
        {
            tbxV121.Text
                = ((int)getV121ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV121bit4_Checked(object sender, RoutedEventArgs e)
        {
            tbxV121.Text
                = ((int)getV121ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV121bit4_Unchecked(object sender, RoutedEventArgs e)
        {
            tbxV121.Text
                = ((int)getV121ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV121bit5_Checked(object sender, RoutedEventArgs e)
        {
            tbxV121.Text
                = ((int)getV121ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV121bit5_Unchecked(object sender, RoutedEventArgs e)
        {
            tbxV121.Text
                = ((int)getV121ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV121bit6_Checked(object sender, RoutedEventArgs e)
        {
            tbxV121.Text
                = ((int)getV121ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV121bit6_Unchecked(object sender, RoutedEventArgs e)
        {
            tbxV121.Text
                = ((int)getV121ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV121bit7_Checked(object sender, RoutedEventArgs e)
        {
            tbxV121.Text
                = ((int)getV121ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV121bit7_Unchecked(object sender, RoutedEventArgs e)
        {
            tbxV121.Text
                = ((int)getV121ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV121bit8_Checked(object sender, RoutedEventArgs e)
        {
            tbxV121.Text
                = ((int)getV121ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void cbxV121bit8_Unchecked(object sender, RoutedEventArgs e)
        {
            tbxV121.Text
                = ((int)getV121ByteValue()).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void sliderV122_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            txtV122dec.Content
                = Convert.ToString((int)sliderV122.Value, 10);
            tbxV122.Text
                = ((int)sliderV122.Value).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void sliderV123_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            txtV123dec.Content
                = Convert.ToString((int)sliderV123.Value, 10);
            tbxV123.Text
                = ((int)sliderV123.Value).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void sliderV124_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            txtV124dec.Content
                = Convert.ToString((int)sliderV124.Value, 10);
            tbxV124.Text
                = ((int)sliderV124.Value).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void sliderV125_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            txtV125dec.Content
                = Convert.ToString((int)sliderV125.Value, 10);
            tbxV125.Text
                = ((int)sliderV125.Value).ToString("X2");
            tbxV126.Text = makeCheckSum().ToString("X2");
        }

        private void mainWindow_Closed(object sender, EventArgs e)
        {
            if (serialPort.IsOpen)
            {
                serialPort.Close();
            }
        }

        private void btnSend_Click(object sender, RoutedEventArgs e)
        {
            // 送信データ用。
            byte[] sendData = new byte[8];

            btnSend.IsEnabled = false;

            try
            {
                if (true == makeRoboXeroComand(ref sendData))
                {
                    for (int i = 0; i < 3; i++)
                    {
                        if (false == sendRoboXeroCommand(sendData))
                            throw new System.ArgumentException("シリアル送信中にエラー。");
                    }
                }

            }
            catch (Exception ex)
            {
                string errMsg = "送信ボタン処理中にエラー";
                errMsg += ex.Message;
                Console.WriteLine(errMsg);
                MessageBox.Show(errMsg);
            }
            finally
            {
                btnSend.IsEnabled = true;
            }
        }
    }
}
